﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace ChineseChess.Game.AI
{
    public class Ai6:BaseAi
    {
        /// <summary>
        /// Ai的算法
        /// </summary>
        /// <param name="pieceList">当前局面</param>
        /// <param name="canvas"></param>
        /// <param name="deep">计算深度</param>
        public static void Run(List<Piece> pieceList, Canvas canvas, int deep = 3)
        {
            List<Piece> pies = pieceList; 
            initTable2();
            Moves mv = MiniMax(deep, pies, false);
            
            Piece p = clearPiece(pieceList, (int)mv.p.X, (int)mv.p.Y);//吃掉子
            //MessageBox.Show(mv.pie.Name.ToString() + mv.pie.X + "," + mv.pie.Y + ", " + mv.p.ToString());
            if (p != null)
            {
                canvas.Children.Remove(p);
            }

            for (int i = 0; i < pieceList.Count; i++)
            {
                var pie = pieceList[i];
                if (pie.X == mv.pie.X && pie.Y == mv.pie.Y)
                {
                    pie.X = (int)mv.p.X;
                    pie.Y = (int)mv.p.Y;
                    pie.InvalidateVisual();
                }
            }
        }

        private static Moves MiniMax(int depth, List<Piece> pies, bool isred)
        {
            int bestvalue, value;
            Moves bestMv = null;
            if(depth == 0)
            {
                Moves mv = new Moves();
                bestvalue = evaluate(pies, isred);
                return mv; 
            }

            if(isred)
            {
                bestvalue = int.MinValue;
            }
            else
            {
                bestvalue = int.MaxValue;
            }

            var moves = generateMoves(pies, isred); //生成全部走法

            Moves move = null;
            for (int i = 0; i < moves.Count; i++)
            {
                move = moves[i]; 
                Piece pie = move.pie;
                int oldX = move.pie.X;
                int oldY = move.pie.Y;
                int newX = (int)move.p.X;
                int newY = (int)move.p.Y;
                Piece eatedPie = clearPiece(pies, newX, newY);
                pie.X = newX;
                pie.Y = newY;

                if (eatedPie != null && eatedPie.Name == ChessName.将)
                {   //被吃的是老将，撤销这个走法
                    pie.X = oldX;
                    pie.Y = oldY;
                    if (eatedPie != null)
                    {
                        pies.Add(eatedPie);
                    }
                    Moves mv = move;
                    bestvalue = 99999;
                    return mv;
                }
                value = MiniMax(depth - 1, pies, !isred).score;
                //撤销这个走法
                pie.X = oldX;
                pie.Y = oldY;
                if (eatedPie != null)
                {
                    pies.Add(eatedPie);
                }

                if(isred)
                {
                    bestMv = move;
                    bestvalue = Math.Max(value, bestvalue);
                    move.score = bestvalue;
                }
                else
                {
                    bestMv = move;
                    bestvalue = Math.Min(value, bestvalue);
                    move.score = bestvalue;
                }
            }
            return bestMv;
        }
    }
}
